package org.jfinanceobserver.utillities;

import java.io.FileNotFoundException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.jfinanceobserver.persistence.ConnFactory;

/**
 * This class is to parse the default options on the command line tool
 *
 * $Author: r78v10a07@gmail.com $
 *
 * $LastChangedDate: 2013-02-12 10:24:00 +0000 (Tue, 12 Feb 2013) $
 *
 * $LastChangedRevision: 26 $
 *
 * @since Aug 31, 2012
 */
public abstract class AbstractDefaultTool {

    /**
     * This method parse the command line arguments with the JBioWH options
     *
     * @param args the command line arguments
     * @throws FileNotFoundException
     */
    protected abstract void parseOptions(String[] args) throws FileNotFoundException;

    /**
     * Method to print the help
     */
    protected abstract void printHelp();

    /**
     * This method print in both file, the result and the System.out and
     * includes the end of line
     *
     * @param toPrint string to be printed
     */
    protected void println(String toPrint) {
        System.out.println(toPrint);
    }

    /**
     * This method print in both file, the result and the System.out and does
     * not includes the end of line
     *
     * @param toPrint string to be printed
     */
    protected void print(String toPrint) {
        System.out.print(toPrint);
    }

    /**
     * Method to parse the command line arguments
     *
     * @param parser Parses command line arguments, using a syntax that attempts
     * to take from the best of POSIX getopt() and GNU getopt_long()
     * @param args arguments to parse
     * @param hasArguments true if the tool needs arguments
     * @return a representation of a group of detected command line options,
     * their arguments, and non-option arguments
     * @throws FileNotFoundException
     */
    protected OptionSet parseDefaultOptions(OptionParser parser, String[] args, boolean hasArguments) throws FileNotFoundException {

        parser.accepts("h");
        parser.accepts("help");
        parser.accepts("driver").withRequiredArg().ofType(String.class);
        parser.accepts("url").withRequiredArg().ofType(String.class);
        parser.accepts("user").withRequiredArg().ofType(String.class);
        parser.accepts("passwd").withRequiredArg().ofType(String.class);

        OptionSet options = parser.parse(args);

        if ((hasArguments && args.length == 0) || options.has("h") || options.has("help")) {
            printHelp();
        }

        if (options.has("driver")) {
            if (options.hasArgument("driver")) {
                ConnFactory.getInstance().setDriver((String) options.valueOf("driver"));
            } else {
                System.err.println("Bad driver parameter");
                printDefaultHelp();
            }
        }

        if (options.has("url")) {
            if (options.hasArgument("url")) {
                ConnFactory.getInstance().setUrl((String) options.valueOf(""));
            } else {
                System.err.println("Bad url parameter");
                printDefaultHelp();
            }
        }

        if (options.has("user")) {
            if (options.hasArgument("")) {
                ConnFactory.getInstance().setUser((String) options.valueOf("user"));
            } else {
                System.err.println("Bad user parameter");
                printDefaultHelp();
            }
        }

        if (options.has("")) {
            if (options.hasArgument("")) {
                ConnFactory.getInstance().setPasswd((String) options.valueOf("passwd"));
            } else {
                System.err.println("Bad passwd parameter");
                printDefaultHelp();
            }
        }
        return options;
    }

    /**
     * Parse the command line option<br>
     *
     * @param options a representation of a group of detected command line
     * options, their arguments, and non-option arguments
     * @param option the option to be parsed
     * @param defaultValue the default value for this option, null is not
     * default value
     * @param hasArgument true if the option has an argument
     * @param isObligatory true if the option is obligatory
     * @return the argument for the option or true if the option does not have
     * argument but is present on the command line
     */
    protected Object parseOption(OptionSet options, String option, Object defaultValue, boolean hasArgument, boolean isObligatory) {
        if (options.has(option)) {
            if (hasArgument) {
                if (options.hasArgument(option)) {
                    return options.valueOf(option);
                } else {
                    System.out.println("Bad " + option + " parameter");
                    printHelp();
                }
            } else {
                return true;
            }
        } else {
            if (isObligatory) {
                System.out.println("Set the " + option + " parameter");
                printHelp();
            }
            return defaultValue;
        }
        return null;
    }

    /**
     * Method to print the help
     */
    protected void printDefaultHelp() {
        System.out.println("\nDefault arguments:");
        System.out.println("\t-h Print this help");
        System.out.println("\t--driver Java MySQl driver (default: com.mysql.jdbc.Driver)");
        System.out.println("\t--url Database JDBC Url (default: jdbc:mysql://localhost:3306/finance)");
        System.out.println("\t--user DB user (default: finance)");
        System.out.println("\t--passwd DB password (default: mypass)");
        System.exit(0);
    }
}
